<?php
/**
 * 上传服务
 *
 * User: Jay
 * Date: 2018/8/9
 */

namespace ServiceBundle\Services;

use BaseBundle\Controller\BaseController;
use BaseBundle\Tool\AliYunOss;
use Gregwar\Image\Image;
use RedUnicorn\SymfonyKernel\Bundle\UnicornBundle\Services\Tools\Files;

class Update extends BaseController
{
    private $file_types = array(
        //图片
        0 => array(
            'types' => array('image/png', 'image/gif', 'image/jpg', 'image/jpeg', 'image/x-icon'),
            'size' => '10M',
            'title' => '图片'
        ),
        //视频
        1 => array(
            'types' => array('video/mp4','video/x-msvideo','video/3gpp'),
            'size' => '100M',
            'title' => '视频'
        ),
        //音频
        2 => array(
            'types' => array('audio/mpeg'),
            'size' => '100M',
            'title' => '音频'
        ),
        //文件
        3 => array(
            'types' => array('application/msword', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint',
                'application/pdf', 'application/octet-stream','application/doc','application/zip','application/excel',
                'application/rar','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                'application/vnd.openxmlformats-officedocument.wordprocessingml.document'),
            'size' => '100M',
            'title' => '文件'
        ),
        //压缩包
        4 => array(
            'types' => array('application/zip', 'application/rar'),
            'size' => '100M',
            'title' => '压缩文件'
        ),
        //表格
        5 => array(
            'types' => array('application/vnd.ms-excel','application/excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-office'),
            'size' => '100M',
            'title' => '表格'
        )
    );

    /**
     * 上传文件
     *
     * @param int $file_type
     * @param null $filename
     * @param string $inputName
     * @param string $path
     * @param boolean $is_save_local 是否保存在本地
     * @return array
     */
    public function upload($file_type = 0, $filename = null, $inputName = 'request', $path = '', $is_save_local = true)
    {
        $result = ['errorCode' => 1, 'message' => ['message' => '', 'key' => $inputName, 'raw_value' => '']];

        if(!(isset($_FILES[$inputName]) && $_FILES[$inputName]['name'])){
            $result['message']['message'] = '上传失败,未获得资源';
            return $result;
        }

        if(!isset($this->file_types[$file_type])){
            $result['message']['message'] = '上传失败,类型不存在';
            return $result;
        }

        if(empty($path)){
            if($is_save_local) {
                $path = implode(DIRECTORY_SEPARATOR, [$this->get('unicorn.files')->getUploadSaveRootDirName(), $this->getRuleGenerationPath()]);
            }else{
                $path = implode(DIRECTORY_SEPARATOR, [$this->get('unicorn.files')->getUploadSaveRootDirName(), 'temporary']);
            }
        }

        $this->mkdirToPath($path);

        $storage = new \Upload\Storage\FileSystem($path);
        $file = new \Upload\File($inputName, $storage);
        $file->setName(empty($filename) ? $this->getDefFileName() : $filename);

        if(empty($file->getPathname())){
            $result['message']['message'] = '上传失败,'. $this->file_types[$file_type]['title'] . '过大';
            return $result;
        }

        //验证上传类型
        $file->addValidations(array(
            //验证文件类型  MimeType List => http://www.iana.org/assignments/media-types/media-types.xhtml
            new \Upload\Validation\Mimetype($this->file_types[$file_type]['types']),
            //验证文件大小  use "B", "K", M", or "G"
            new \Upload\Validation\Size($this->file_types[$file_type]['size']),
        ));

        // Access data about the file that has been uploaded
        $data = array(
            'path_name' =>  $path . '/' . $file->getNameWithExtension(),
            'name'       => $file->getNameWithExtension(),
            'extension'  => $file->getExtension(),
            'mime'       => $file->getMimetype(),
            'size'       => $file->getSize(),
            'md5'        => $file->getMd5(),
            'dimensions' => $file->getDimensions(),
            'original_name' => $_FILES[$inputName]['name']
        );

        $file_save_path =  implode(DIRECTORY_SEPARATOR, [Files::rootdir(), 'web' , $path, $file->getNameWithExtension()]);

        // Try to upload file
        try {
            // Success!
            $file->upload();

            //压缩图片
            if($file_type == 0){
                $width = self::$request->get('width', 0);
                $height = self::$request->get('height', 0);
                if($width != 0 && $height != 0){
                    Image::open($file_save_path)
                        ->zoomCrop($width, $height)
                        ->save($path);
                }
            }

            $result['errorCode']  = 0;
            $result['data'] = $data;
            $result['message']['message'] = $this->file_types[$file_type]['title'] . '上传成功';

            if (!$is_save_local) {
                //TODO 上传至资源服务器
            }

            $result['data']['server_path'] = $this->get('unicorn.files')->getFilePath($result['data']['path_name']);

        } catch (\Exception $e) {
            // Fail!
            $errorMessages = $file->getErrors();

            if(empty($errorMessages)){
                $errorMessages = $e->getMessage();
                unlink($file_save_path);
            }else{
                $errorMessages = $errorMessages[0];
            }

            $this->get('unicorn.files')->writeLog($errorMessages, 'upload.log');

            $result['errorCode'] = 1;
            $result['data'] = array();
            $result['message']['message'] = $this->file_types[$file_type]['title'] .'上传失败';
            $result['message']['raw_value'] = $file->getMimetype();
        }

        return $result;
    }

    /**
     * 得到规则生成路径
     *
     * @return false|string
     */
    private function getRuleGenerationPath()
    {
        return date('Y-m');
    }

    /**
     * 文件默认名称
     *
     * @return string
     */
    private function getDefFileName()
    {
        return uniqid();
    }

    /**
     * 根据路径创建目录
     *
     * @param $path
     */
    private function mkdirToPath($path)
    {
        if(!file_exists($path)) {
            $dirs = explode('/' , $path);
            $count = count($dirs);
            $path = '.';
            for ($i = 0; $i < $count; ++$i) {
                $path .= '/' . $dirs[$i];
                if(!is_dir($path)){//不是目录
                    mkdir($path,0755);
                }
            }
        }
    }
}